<template>
  <div class="AI-dialog" v-if="contextLength && (codeHelp || isHGKJteam)">
    <div @click="AIHelp" class="AI-btn">
      <!-- <el-image :src="childRobot" class="AI-cion"> </el-image> -->
      <span class="emoji">🙋🏻</span>
      <span> 代码协助 </span>
    </div>
    <el-dialog
      v-if="AICodeHelpDialogVisible"
      v-model="AICodeHelpDialogVisible"
      width="60%"
      append-to=".ojSass"
      draggable
      overflow
    >
      <template #header>
        <span class="icon-text el-dialog__header-title">
          <el-icon class="text-primary">
            <Guide />
          </el-icon>
          代码协助(AI)-{{ question?.name }}
        </span>
      </template>
      <div>
        <div class="AI-dialog-hdeader">
          <div class="icon-text">
            <!-- :loading="isFirstRequestLoading || isSecondRequestLoading" status === 'submitted' || status === 'streaming' -->
            <el-button
              :loading="myIsLoading"
              class="AI-start-btn"
              size=""
              type=""
              plain
              @click="handleSubmit"
            >
              <!-- <el-image :src="childRobot" class="AI-cion"> </el-image> -->
              <span class="emoji">🙋🏻</span>
              <span style="display: inline-block; margin-left: 4px">
                {{ hasAIResponse ? "重新生成代码协助" : "生成代码协助" }}
              </span>
            </el-button>
            <AIWarningTips :show="true" />
          </div>
          <el-button
            v-show="myIsLoading"
            class="AI-start-btn margin0"
            size=""
            type=""
            plain
            @click="clear(false)"
          >
            <!-- <el-image :src="childRobot" class="AI-cion"> </el-image> -->
            <span class="emoji">🙅🏻</span>
            <span style="display: inline-block; margin-left: 4px">
              停止分析
            </span>
          </el-button>
        </div>
        <div class="AI-dialog-body" v-if="messages.length">
          <div class="chat-messages" ref="messagesContainer">
            <div
              v-for="(msg, index) in messages"
              :key="index"
              class="message"
              :class="msg.role"
            >
              <div class="message-content">
                <div
                  v-if="msg.role === 'assistant'"
                  v-html="formatAIResponse(msg.content)"
                />
              </div>
            </div>
          </div>
        </div>
      </div>
    </el-dialog>
  </div>
</template>

<script lang="ts" setup>
import { useChat } from "@ai-sdk/vue";
import { ElMessage } from "element-plus";
import { marked } from "marked";
import { v4 } from "uuid";
import {
  computed,
  inject,
  nextTick,
  onUnmounted,
  ref,
  toRefs,
  watch,
} from "vue";
import { useRouter } from "vue-router";
import { useStore } from "vuex";
import { jilurizhi } from "../../../../api";
import AIWarningTips from "../../../../components/AIWarningTips.vue";
import { Storekey } from "../../../../interface";
import Studycodemodel from "../../../../mysql_interface/studycodemodel";
import { adminTeamId, AILogAction, AILogMethod } from "../../../../util/data";

// 码客行
const tenant_id = inject<string | undefined>("tenant_id", undefined);

// 常量定义
const MIN_CONTENT_LENGTH = 20;
const MIN_SIMILARITY_PERCENT = 60;
const p = defineProps<{
  ID?: number;
  user: Studycodemodel.Iuser;
  question?: Studycodemodel.Iquestion;
  context: string;
  language: string;
}>();
const { ID, question, context, language } = toRefs(p);
const router = useRouter();
const store = useStore(Storekey);
const user = computed(() => store.state.user);
const isAdmin = computed(() => {
  return user.value?.isAdmin;
});
const getteam = computed(() => {
  return store.state.team?.rows || [];
});
const isHGKJteam = computed(() => user.value?.teamid === adminTeamId);
const codeHelp = computed(() => {
  return getteam.value.some((c) => c?.other?.codeHelp);
});
const contextLength = computed(() => {
  return question.value?.context?.length || 0 >= MIN_CONTENT_LENGTH;
});
// 新增状态管理
const currentRequestId = ref<string>("");
const shouldContinueSecondRequest = ref(false);
const AICodeHelpDialogVisible = ref(false);
const messagesContainer = ref<HTMLElement>();
// TODO 这两个变量暂时没用
const isFirstRequestLoading = ref(false);
const isSecondRequestLoading = ref(false);
// 自定义loading
const isStreaming = ref(false);
const myIsLoading = computed(() => {
  return isStreaming.value && isLoading.value;
});
// 是否有AI回复
const hasAIResponse = computed(() => {
  return messages.value.some((msg) => msg.role === "assistant");
});
function getCookie(name: string) {
  const value = `; ${document.cookie}`;
  const parts = value.split(`; ${name}=`);
  if (parts.length === 2) return parts.pop()?.split(";").shift();
  return null;
}
const headers = computed(() => ({
  "x-csrf-token": getCookie("csrfToken") || "",
  "Content-Type": "application/json",
}));
// 1. 获取当前域名
const currentHostname = window.location.hostname;
const isPublicHterobot = currentHostname === "public.hterobot.com";
// 2. 动态 API 配置（避免正则，逻辑更清晰）
const getApiBaseUrl = () => {
  if (process.env.NODE_ENV === "development") {
    return ""; // 开发环境用代理（如 '/api'）
  }
  if (isPublicHterobot) {
    return ``; // public.hterobot.com 直接使用当前域名
  }
  return tenant_id ? "https://oj.accoders.cn" : "https://oj.hterobot.com";
};
const API_BASE_URL = getApiBaseUrl();
const API_ENDPOINT = "/api/studycode/v1/user/chat/completions";
const {
  setMessages,
  messages,
  input,
  handleSubmit: originalHandleSubmit,
  status,
  stop,
  data: responseData,
  isLoading,
} = useChat({
  api: `${API_BASE_URL}${API_ENDPOINT}`,
  headers: headers.value,
  streamProtocol: "data",
  body: {
    questionid: ID.value,
    userid: user.value?.ID,
    code: context.value,
    uuid: v4(),
    next: false,
  },
  onResponse: (response) => {
    isStreaming.value = true;
  },
  onFinish: (message, options) => {
    // 如果不是当前有效请求则忽略
    if (!currentRequestId.value) return;
    // 只有在第一次请求时才检查关联度
    if (!shouldContinueSecondRequest.value) {
      const content = message.content;
      // 使用正则表达式提取内容中的百分比数字
      const percentageMatch = content.match(/(\d+)%/);
      const percentage = percentageMatch ? parseInt(percentageMatch[1]) : 0;
      if (percentage >= MIN_SIMILARITY_PERCENT) {
        // 标记准备发送第二次请求
        shouldContinueSecondRequest.value = true;

        isFirstRequestLoading.value = false;
        isSecondRequestLoading.value = true;
        // 使用 setTimeout 让UI有时间更新
        setTimeout(() => {
          if (shouldContinueSecondRequest.value) {
            sendAIRequest(true); // 显式发起第二次请求
          }
        }, 100);
      } else {
        ElMessage.warning(
          `代码与题目的关联度仅为${percentage}%，未达到代码协助要求（关联度>=${MIN_SIMILARITY_PERCENT}%）`
        );

        isFirstRequestLoading.value = false;
      }
    }
    //
    // console.log("onFinish:", options, message, status.value, isLoading.value);
    isStreaming.value = false;
  },
  onError: (error) => {
    if (error.name === "AbortError") return;
    ElMessage.error(`请求错误: ${error.message}`);
    clear(false);
  },
});
// 重置
function clear(completeReset = true) {
  stop(); // 取消当前正在进行的任何请求
  // 使之前的回调无效
  currentRequestId.value = "";
  shouldContinueSecondRequest.value = false;

  isFirstRequestLoading.value = false;
  isSecondRequestLoading.value = false;

  if (completeReset) {
    setMessages([]);
    input.value = "";
  }
}
// 统一请求
async function sendAIRequest(isSecondRequest: boolean) {
  // 如果不是第二次请求，则清空消息
  if (!isSecondRequest) {
    clear();
    setMessages([]);
  }
  const requestId = Date.now().toString();
  currentRequestId.value = requestId;
  try {
    await originalHandleSubmit(new Event("submit"), {
      allowEmptySubmit: true,
      body: {
        questionid: ID.value,
        code: `${language.value == "Python" ? "#" : "//"}这是第0行\r\n${
          context.value
        }`,
        userid: user.value?.ID,
        next: isSecondRequest,
      },
    });
    // 检查是否仍然是当前有效请求
    if (currentRequestId.value !== requestId) return;
    scrollToBottom();
  } catch (error) {
    if (currentRequestId.value !== requestId) return;
    if ((error as Error).name !== "AbortError") {
      ElMessage.error("请求失败: " + (error as Error).message);
    }
  } finally {
    if (currentRequestId.value === requestId) {
      isFirstRequestLoading.value = false;
      isSecondRequestLoading.value = false;
    }
  }
}
//
const handleSubmit = async (e: Event) => {
  clear(false); // 不完全重置，保留消息

  isFirstRequestLoading.value = true;
  shouldContinueSecondRequest.value = true;
  // 记录
  recordLog();
  await sendAIRequest(false);
};
async function AIHelp() {
  // 1. 内容验证
  if (!context.value || context.value.length < MIN_CONTENT_LENGTH) {
    ElMessage.error(`代码内容太少，至少需要 ${MIN_CONTENT_LENGTH} 个字符`);
    return;
  }
  // 2. 打开对话框
  AICodeHelpDialogVisible.value = true;
  // 3. 如果没有消息记录则自动提交（首次请求）
  if (messages.value.length === 0) {
    try {
      await handleSubmit(new Event("auto-submit"));
      // 自动滚动到底部
      nextTick(() => {
        scrollToBottom();
      });
    } catch (error) {
      console.error("AI请求失败:", error);
    }
  }
}
const scrollToBottom = () => {
  if (messagesContainer.value) {
    nextTick(() => {
      messagesContainer.value?.scrollTo({
        top: messagesContainer.value.scrollHeight,
        behavior: "smooth",
      });
    });
  }
};
const formatAIResponse = (content: string): string => {
  let formatted = content.replace(/^```markdown\n/, "").replace(/```\s*$/, "");
  if ((formatted.match(/```/g) || []).length % 2 !== 0) {
    formatted += "\n```";
  }
  const cleanContent = formatted
    .replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, "")
    .replace(/on\w+="[^"]*"/g, "");
  marked.setOptions({
    breaks: true,
    gfm: true,
  });
  return marked.parse(cleanContent || "");
};

// 组件卸载时清理
onUnmounted(() => {
  clear();
});

// 题目切换时完全重置
watch(
  () => ID.value,
  () => {
    clear();
    AICodeHelpDialogVisible.value = false;
  }
);

// 记录日志函数
function recordLog() {
  // 处理代码截断
  const maxCodeLength = 8000;
  const codePreview =
    context.value.length > maxCodeLength
      ? context.value.substring(0, maxCodeLength) + "..."
      : context.value;

  const arr: [string, any][] = [];
  // 基础信息
  arr.push(["_method_", AILogMethod.CodeAssistance]);
  arr.push(["type", "AI"]);
  arr.push(["questionid", ID.value]);
  arr.push(["questionname", question.value?.name]);
  let body: { [key: string]: any } = {
    language: language.value,
    code_length: context.value.length,
    code: codePreview,
    action: AILogAction.CODE_ASSISTANCE,
  };
  // arr.push(["language", language.value]);
  // arr.push(["code_length", context.value.length]);
  // arr.push(["code", codePreview]);
  // arr.push(["action", AILogAction.CODE_ASSISTANCE]);
  arr.push(["body", JSON.stringify(body)]);
  // 调用日志接口
  console.log("Code Help Log:", arr);
  jilurizhi(arr);
}
</script>

<style scoped>
/* 保持原有的样式不变 */
.AI-dialog {
  --discuss-padding: 16px;
  display: block;
  width: 90px;
  height: 36px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.AI-btn {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: space-evenly;
}

.AI-cion {
  width: 26px;
}

.AI-dialog-hdeader {
  display: flex;
  justify-content: space-between;
  align-items: center;

  margin-bottom: 10px;
}

.AI-start-btn {
  height: 36px;
  border-radius: 4px;
  margin-right: 10px;
}

.chat-messages {
  flex: 1;
  overflow-y: auto;
  padding: 12px;
  border: 1px solid var(--el-border-color);
  border-radius: 8px;
  display: flex;
  flex-direction: column;
  max-height: 60vh;
  position: relative;
}

.message.assistant .message-content {
  padding: 4px 10px;
  border-radius: 8px;
  color: #000;
}

/* Markdown样式 */
.message-content :deep(h1) {
  font-size: 20px;
  font-weight: 600;
  margin: 16px 0 8px;
}

.message-content :deep(h2) {
  font-size: 18px !important;
  font-weight: 600;
  margin: 14px 0 8px;
}

.message-content :deep(h3) {
  font-size: 16px !important;
  font-weight: 600;
  margin: 12px 0 8px;
  padding-bottom: 4px;
}

.message-content :deep(h4) {
  font-size: 15px !important;
}

.message-content :deep(h5) {
  font-size: 15px !important;
}

.message-content :deep(p) {
  margin: 8px 0;
  line-height: 1.6;
}

.message-content :deep(ul) {
  margin: 8px 0;
  padding-left: 24px;
}

.message-content :deep(li) {
  margin: 6px 0;
  line-height: 1.6;
}

.message-content :deep(.inline-code) {
  font-family: "Courier New", monospace;
  background: #f5f7fa;
  padding: 2px 4px;
  border-radius: 4px;
  color: #e96900;
}

.message-content :deep(pre) {
  background-color: #f6f8fa;
  padding: 1em;
  border-radius: 6px;
  overflow-x: auto;
  margin: 1em 0;
}

.message-content :deep(code) {
  font-family: "Courier New", monospace;
  background-color: #f6f8fa;
  padding: 0.2em 0.4em;
  border-radius: 3px;
  color: #606266;
}

.message-content :deep(blockquote) {
  border-left: 4px solid #409eff;
  padding: 0.5em 1em;
  margin: 1em 0;
  background-color: #f5f7fa;
  color: #606266;
}
</style>
